#include "ssd1315/ssd1315.h"
#include "ssd1315/ssd1315_font.h"
#include <stdio.h>

//几个变量声明

static I2CWriteInterface do_write_i2c_ = NULL;


#define SCREEN_ADDR   0x3C  ///< 屏幕从设备地址

#define SCREEN_ROW    128   ///< 屏幕行数
#define SCREEN_COLS   64    ///< 屏幕列数

#define WRITE_CMD     0x00  ///< 写指令
#define WRITE_DATA    0X40  ///< 写数据

static void DoWriteCmd(UInt8 cmd)
{
    UInt8 send_frame[2] = {WRITE_CMD, cmd};

    if (do_write_i2c_)
        do_write_i2c_(SCREEN_ADDR, send_frame, sizeof(send_frame));
}

static void DoWriteData(UInt8 data)
{
    UInt8 send_frame[2] = {WRITE_DATA, data};

    if (do_write_i2c_)
        do_write_i2c_(SCREEN_ADDR, send_frame, sizeof(send_frame));
}

static void TSSD1315_SetPos(UInt8 x, UInt8 y)
{
    DoWriteCmd(0xb0 + y);
    DoWriteCmd(((x & 0xf0) >> 4) | 0x10);
    DoWriteCmd(x & 0x0f);
}

static void DisplayLogo(void)
{
    for (Int32 y = 0; y < 8; y ++)
    {
        TSSD1315_SetPos(0, y);
        for (Int32 x = 0; x < 128; x ++)
        {
            DoWriteData(Flogo[128 * y + x]);
        }
    }
}

//初始化oled屏幕
void TSSD1315_Init(I2CWriteInterface i2c_write)
{
    do_write_i2c_ = i2c_write;

    UInt8 init_cmd_list[] = {
        0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F,
        0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12,
        0xD8, 0x30, 0x8D, 0x14, 0xAF
    };

    for (Int32 idx = 0; idx < sizeof(init_cmd_list); idx ++)
    {
        DoWriteCmd(init_cmd_list[idx]);
    }

    DisplayLogo();
}
//清屏size12 size16要清两行，其他函数有类似情况
void TSSD1315_Clear()
{
    for (UInt8 i = 0; i < 8; i ++)
    {
        DoWriteCmd(0xb0 + i);
        DoWriteCmd(0x00);
        DoWriteCmd(0x10);

        for (UInt8 n = 0; n < SCREEN_ROW; n ++)
        {
            DoWriteData(0);
        }
    }
}
//清行
void TSSD1315_ClearRow(UInt8 i)
{
    DoWriteCmd(0xb0 + i);
    DoWriteCmd(0x00);
    DoWriteCmd(0x10);

    for(UInt8 n = 0; n < SCREEN_ROW; n ++)
    {
        DoWriteData(0);
    }
}
//开启OLED显示
void TSSD1315_DisplayOn(void)
{
    DoWriteCmd(0X8D);  //SET DCDC命令
    DoWriteCmd(0X14);  //DCDC ON
    DoWriteCmd(0XAF);  //DISPLAY ON
}
//关闭OLED显示
void TSSD1315_DisplayOff(void)
{
    DoWriteCmd(0X8D);  //SET DCDC命令
    DoWriteCmd(0X10);  //DCDC OFF
    DoWriteCmd(0XAE);  //DISPLAY OFF
}

//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void TSSD1315_ShowChar(UInt8 x, UInt8 y, UInt8 chr, TFont font)
{
    UInt8 ch_idx = 0;
    Int32 idx = 0;

    ch_idx = chr - ' ';//得到偏移后的值

    switch (font)
    {
    case kFont8x16:
    {
        if (ch_idx >= sizeof(F8x16) / sizeof(F8x16[0]))
            return;

        TSSD1315_SetPos(x, y);

        for (idx = 0; idx < 8; idx ++)
        {
            DoWriteData(F8x16[ch_idx][idx]);
        }

        TSSD1315_SetPos(x, y + 1);

        for (idx = 0; idx < 8; idx ++)
        {
            DoWriteData(F8x16[ch_idx][idx + 8]);
        }
    }
        break;
    case kFont6x8:
    {
        if (ch_idx >= sizeof(F6x8) / sizeof(F6x8[0]))
            return;

        TSSD1315_SetPos(x, y);

        for (idx = 0; idx < 6; idx ++)
        {
            DoWriteData(F6x8[ch_idx][idx]);
        }
    }
        break;

    default:
        break;
    }
}
 //显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式    0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void TSSD1315_ShowNum(UInt8 x, UInt8 y, UInt32 num, TFont font)
{
    UInt32 temp;
    UInt8  ch = 0;
    UInt8  x_offset = 0;
    UInt8  ch_arr[10] = {0};
    UInt8  ch_arr_size = 0;

    temp = num;

    do
    {
        ch = temp % 10 + '0';
        temp = temp / 10;

        ch_arr[ch_arr_size] = ch;

        ch_arr_size ++;
    }
    while (temp > 0);

    for (Int32 idx = ch_arr_size - 1; idx >= 0; idx --)
    {
        TSSD1315_ShowChar(x + x_offset, y, ch_arr[idx], font);

        switch (font)
        {
        case kFont6x8:
            x_offset += 6;
            break;
        case kFont8x16:
            x_offset += 8;
        default:
            break;
        }
    }
}
//显示一个字符号串
void TSSD1315_ShowString(UInt8 x, UInt8 y, UInt8 *chr, TFont font)
{
    UInt8 idx = 0;
    UInt8  x_offset = 0;

    while (chr[idx] != '\0')
    {
        TSSD1315_ShowChar(x + x_offset, y, chr[idx], font);

        switch (font)
        {
        case kFont6x8:
            x_offset += 6;
            break;
        case kFont8x16:
            x_offset += 8;
        default:
            break;
        }

        idx ++;
    }
}

//显示一个浮点数
void TSSD1315_ShowFloat(UInt8 x, UInt8 y, Float num, UInt8 max_len, TFont font)
{
    UInt32 temp;
    UInt8  ch = 0;
    UInt8  x_offset = 0;
    UInt8  ch_arr[11] = {0};
    UInt8  ch_arr_size = 0;
    UInt8  dot_idx = 0;

    ch_arr_size = snprintf(ch_arr, max_len, "%f", num);

    for (Int32 idx = 0; idx < ch_arr_size; idx ++)
    {
        TSSD1315_ShowChar(x + x_offset, y, ch_arr[idx], font);

        switch (font)
        {
        case kFont6x8:
            x_offset += 6;
            break;
        case kFont8x16:
            x_offset += 8;
        default:
            break;
        }
    }
}
// //显示汉字
// //hzk 用取模软件得出的数组
// void TSSD1315_ShowOther(UInt8 x,UInt8 y,UInt8 no)
// {
//     // UInt8 t,adder=0;
//     // TSSD1315_SetPos(x,y);
//     // for(t=0;t<16;t++)
//     //     {
//     //             DoWriteData(Hzk[2*no][t]);
//     //             adder+=1;
//     //  }
//     //     TSSD1315_SetPos(x,y+1);
//     // for(t=0;t<16;t++)
//     //         {
//     //             DoWriteData(Hzk[2*no+1][t]);
//     //             adder+=1;
//     //   }
// }
